import type { VNode, VNodeChild } from "vue";
import type { SelectGroupOption } from "naive-ui";
import type { Dic, PopPlacement } from "@/_interface";
import type {
  SelectBaseOption,
  OnUpdateValue as OnUpdateOfSelect,
} from "naive-ui/es/select/src/interface";
import {
  CascaderOption as CascaderItemOption,
  OnUpdateValue as OnUpdateOfCascader,
} from "naive-ui/es/cascader/src/interface";

export type InputOption = {
  type?: "input" | "textarea" | "password";
  size?: "tiny" | "small" | "medium" | "large";
  placeholder?: string;
  disabled?: boolean;
  autofocus?: boolean;
  autosize?:
    | boolean
    | {
        minRows?: number | undefined;
        maxRows?: number | undefined;
      };
  clearable?: boolean;
  maxlength?: number;
  minlength?: number;
  readonly?: boolean;
  round?: boolean;
  rows?: number;
  showCount?: boolean;
  showPasswordOn?: "click" | "mousedown";
  renderPrefix?: () => VNodeChild;
  renderSuffix?: () => VNodeChild;
  allowInput?: (val: string) => boolean;
  onInput?: (val: string) => void;
  onBlur?: () => void;
  onFocus?: () => void;
  onClear?: () => void;
  onUpdate?: (val: string) => void;
};

export type NumberOption = {
  size?: "tiny" | "small" | "medium" | "large";
  placeholder?: string;
  disabled?: boolean;
  autofocus?: boolean;
  clearable?: boolean;
  readonly?: boolean;
  showButton?: boolean;
  buttonPlacement?: "both" | "right";
  min?: number;
  max?: number;
  step?: number;
  precision?: number;
  controls?: boolean;
  keyboard?: { ArrowUp?: boolean; ArrowDown?: boolean };
  format?: (value: number | null) => string;
  renderPrefix?: () => VNodeChild;
  renderSuffix?: () => VNodeChild;
  onBlur?: () => void;
  onFocus?: () => void;
  onClear?: () => void;
  onUpdate?: (val: number | null) => void;
};

export type RadioItemOption = {
  label: string;
  value: string | number | boolean;
  disabled?: boolean;
};
export type RadioOption = {
  size?: "small" | "medium" | "large";
  disabled?: boolean;
  name?: string;
  button?: boolean;
  onUpdate?: (val: string) => void;
} & Dic<RadioItemOption>;

export type CheckboxItemOption = {
  label: string;
  value: string | number;
  disabled?: boolean;
};
export type CheckboxOption = {
  size?: "small" | "medium" | "large";
  disabled?: boolean;
  max?: number;
  min?: number;
  onUpdate?: (
    value: (string | number)[],
    meta: {
      actionType: "check" | "uncheck";
      value: string | number;
    }
  ) => void;
} & Dic<CheckboxItemOption>;

export type SwitchOption = {
  size?: "small" | "medium" | "large";
  disabled?: boolean;
  loading?: boolean;
  round?: boolean;
  rubberBand?: boolean;
  checkedValue?: string | boolean | number;
  uncheckedValue?: string | boolean | number;
  renderIcon?: () => VNodeChild;
  renderChecked?: () => VNodeChild;
  renderCheckedIcon?: () => VNodeChild;
  renderUnchecked?: () => VNodeChild;
  renderUncheckedIcon?: () => VNodeChild;
  onUpdate?: (val: boolean) => void;
};

export type SelectItemOption = SelectBaseOption | SelectGroupOption;
export type SelectOption = {
  size?: "tiny" | "small" | "medium" | "large";
  disabled?: boolean;
  clearable?: boolean;
  multiple?: boolean;
  filterable?: boolean;
  filter?: (pattern: string, option: SelectBaseOption) => boolean;
  keyboard?: boolean;
  tag?: boolean;
  maxTagCount?: number | "responsive";
  placement?: PopPlacement;
  placeholder?: string;
  clearFilterAfterSelect?: boolean;
  resetMenuOnOptionsChange?: boolean;
  renderHeader?: () => VNodeChild;
  renderAction?: () => VNodeChild;
  renderEmpty?: () => VNodeChild;
  renderArrow?: () => VNodeChild;
  renderLabel?: (option: SelectBaseOption & SelectGroupOption, selected: boolean) => VNodeChild;
  renderOption?: (info: {
    node: VNode;
    option: SelectBaseOption & SelectGroupOption;
    selected: boolean;
  }) => VNodeChild;
  renderTag?: (props: { option: SelectBaseOption; handleClose: () => void }) => VNodeChild;
  onSearch?: (value: string) => void;
  onBlur?: () => void;
  onFocus?: () => void;
  onClear?: () => void;
  onCreate?: (label: string) => SelectBaseOption;
  onScroll?: (e: Event) => void;
  onUpdateShow?: (show: boolean) => void;
  onUpdate?: OnUpdateOfSelect;
} & Dic<SelectItemOption>;

export type { CascaderItemOption };
export type CascaderOption = {
  size: "small" | "medium" | "large";
  disabled?: boolean;
  clearable?: boolean;
  multiple?: boolean;
  filterable?: boolean;
  filter?: (pattern: string, option: CascaderItemOption, path: CascaderItemOption[]) => boolean;
  cascade?: boolean;
  checkStrategy?: "all" | "parent" | "child";
  expandTrigger?: "click" | "hover";
  maxTagCount?: number | "responsive";
  placement?: PopPlacement;
  placeholder?: string;
  separator?: string;
  showPath?: boolean;
  clearFilterAfterSelect?: boolean;
  renderPrefix?: (info: {
    option: CascaderItemOption;
    node: VNode | null;
    checked: boolean;
  }) => VNodeChild;
  renderLabel?: (option: CascaderItemOption, checked: boolean) => VNodeChild;
  renderSuffix?: (info: { option: CascaderItemOption; checked: boolean }) => VNodeChild;
  onLoad?: (option: CascaderItemOption) => Promise<void>;
  onBlur?: () => void;
  onFocus?: () => void;
  onUpdate?: OnUpdateOfCascader;
} & Dic<CascaderItemOption>;
